/**
 * 
 */
package org.t2.backstage.module.player;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.banish.sql.core.util.QuerySet;
import org.gaming.backstage.PageData;
import org.gaming.service.apidoc.annotation.ApiDocument;
import org.gaming.tool.DateTimeUtil;
import org.gaming.tool.ListMapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.t2.backstage.module.gameserver.model.GameChannel;
import org.t2.backstage.module.gameserver.service.GameChannelService;
import org.t2.backstage.module.player.model.PlayerLTV;
import org.t2.backstage.module.player.query.PlayerCommonQuery;
import org.t2.backstage.module.player.service.PlayerLTVService;
import org.t2.backstage.module.player.service.PlayerPayInServerService;
import org.t2.backstage.module.player.vo.PlayerLtvVo;

/**
 * @author YY
 *
 */
@Controller
public class PlayerLTVController {

	@Autowired
	private GameChannelService gameChannelService;
	@Autowired
	private PlayerLTVService playerLTVService;
	@Autowired
	private PlayerPayInServerService playerPayInServerService;
	
	
	@ApiDocument("请求付费LTV数据")
	@RequestMapping(value = "/playerLtv/data.auth")
	@ResponseBody
	public PageData<PlayerLtvVo> data(PlayerCommonQuery query) {
		QuerySet querySet = new QuerySet();
		//渠道选择
		if(query.getChannels() != null && !query.getChannels().isEmpty()) {
			querySet.findInSet("channel_id", query.getChannels());
		}
		//服务器选择
		if(query.getServerUids() != null && !query.getServerUids().isEmpty()) {
			querySet.findInSet("server_uid", query.getServerUids());
		}
		//开始时间
		long startTime = query.getStartTime() * 1000L;
		if(startTime == 0) {
			startTime = DateTimeUtil.monthZeroMillis();
		}
		String startBorn = DateTimeUtil.formatMillis(DateTimeUtil.YYYYMMDD, startTime);
		querySet.addCondition("born >= ?", startBorn);
		//结束时间
		long endTime = query.getEndTime() * 1000L;
		if(endTime > 0) {
			String endBorn = DateTimeUtil.formatMillis(DateTimeUtil.YYYYMMDD, endTime);
			querySet.addCondition("born <= ?", endBorn);
		}
		//LTV只看7天数据
		querySet.addCondition("day_count < ?", 7);
		querySet.limit(1, 100);
		querySet.formWhere();
		
		List<PlayerLTV> playerLTVs = playerLTVService.queryLTV(querySet);
		Map<Integer, Map<Long, List<PlayerLTV>>> bornChannelMap = ListMapUtil.fillTwoListMap(playerLTVs, PlayerLTV::getBorn, PlayerLTV::getChannelId);
		
		Map<String, PlayerLtvVo> resultMap = new HashMap<>();
		
		for(Entry<Integer, Map<Long, List<PlayerLTV>>> bornChannelEntry : bornChannelMap.entrySet()) {
			int born = bornChannelEntry.getKey();
			Map<Long, List<PlayerLTV>> channelMap = bornChannelEntry.getValue();
			
			for(Entry<Long, List<PlayerLTV>> channelEntry : channelMap.entrySet()) {
				long channelId = channelEntry.getKey();
				GameChannel gameChannel = gameChannelService.getEntity(0, channelId);
				String key = born + "_" + channelId;
				
				PlayerLtvVo resultVo = new PlayerLtvVo();
				resultVo.setBornDate(born);
				resultVo.setChannelId(channelId);
				if(gameChannel != null) {
					resultVo.setChannelInfo(gameChannel.getName() + "[" + channelId + "]");
				} else {
					resultVo.setChannelInfo("");
				}
				
				for(PlayerLTV playerLTV : channelEntry.getValue()) {
					if (playerLTV.getDayCount() <= 0) {
						resultVo.setDay0(resultVo.getDay0().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 1) {
						resultVo.setDay1(resultVo.getDay1().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 2) {
						resultVo.setDay2(resultVo.getDay2().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 3) {
						resultVo.setDay3(resultVo.getDay3().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 4) {
						resultVo.setDay4(resultVo.getDay4().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 5) {
						resultVo.setDay5(resultVo.getDay5().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
					if (playerLTV.getDayCount() <= 6) {
						resultVo.setDay6(resultVo.getDay6().add(new BigDecimal(playerLTV.getMoney() / 100)));
					}
				}
				resultMap.put(key, resultVo);
			}
		}
		
		//设置充值总额、付费率信息
		playerPayInServerService.fillPayInfo(query.getChannels(), query.getServerUids(), resultMap.values());
		
		List<String> bornChannelKeys = new ArrayList<>(resultMap.keySet());
		Collections.sort(bornChannelKeys);
//		Collections.reverse(bornChannelKeys);
		
		List<PlayerLtvVo> resultList = new ArrayList<>();
		for(String bornChannelKey : bornChannelKeys) {
			PlayerLtvVo playerLtvVo = resultMap.get(bornChannelKey);
			if(playerLtvVo.getPlayerCount() > 0) {
				BigDecimal createCount = new BigDecimal(playerLtvVo.getPlayerCount());
				playerLtvVo.setDay0(playerLtvVo.getDay0().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay1(playerLtvVo.getDay1().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay2(playerLtvVo.getDay2().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay3(playerLtvVo.getDay3().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay4(playerLtvVo.getDay4().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay5(playerLtvVo.getDay5().divide(createCount, 2, RoundingMode.FLOOR));
				playerLtvVo.setDay6(playerLtvVo.getDay6().divide(createCount, 2, RoundingMode.FLOOR));
			}
			
			resultList.add(playerLtvVo);
		}
		
		PageData<PlayerLtvVo> pageData = new PageData<>();
		pageData.setCount(resultList.size());
		pageData.setData(resultList);
		return pageData;
	}
	
	@ApiDocument("手动触发当天LTV数据统计")
	@RequestMapping(value = "/playerLtv/manual.auth")
	@ResponseBody
	public void manual() {
		playerPayInServerService.countServerRecharge();
		playerLTVService.countLTV(DateTimeUtil.currMillis() + DateTimeUtil.ONE_DAY_MILLIS);
	}
}
